package com.bckj.freshnow.order.trade.execution.create;

import cn.hutool.core.util.NumberUtil;
import com.bckj.fastboot.core.execution.Execution;
import com.bckj.fastboot.core.execution.ExecutionContext;
import com.bckj.freshnow.goods.model.GoodsSkuResponse;
import com.bckj.freshnow.order.entity.TradeItem;
import com.bckj.freshnow.order.entity.TradeOrder;
import com.bckj.freshnow.order.entity.TradeParentOrder;
import com.bckj.freshnow.order.model.CreateTradeOrderRequest;
import com.bckj.freshnow.order.model.TradeItemRequest;
import com.bckj.freshnow.order.trade.fsm.TradeOrderContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 创建订单-拆单
 */
@Component
@RequiredArgsConstructor
public class CreateTradeOrderSplitExecution implements Execution {

    @Override
    public void execute(ExecutionContext context) {
        var ctx = (TradeOrderContext) context;
        Map<String, GoodsSkuResponse> skuInfo = ctx.getSkuInfo();
        CreateTradeOrderRequest request = (CreateTradeOrderRequest) ctx.getRequest();
        List<TradeItem> itemList = request.getItemList().stream().map(p -> {
            TradeItem item = convert(p);
            String skuCode = item.getSkuCode();
            GoodsSkuResponse sku = skuInfo.get(item.getSkuCode());
            Assert.notNull(sku, "商品信息为空 skuCode=" + skuCode);
            item.setGoodsCode(sku.getGoodsCode());
            item.setGoodsName(sku.getGoodsName());
            item.setGoodsImage(sku.getGoodsImage());
            item.setOriginPrice(sku.getOriginPrice());
            return item;
        }).toList();
        splitOrder(ctx, itemList);
    }

    private TradeItem convert(TradeItemRequest dto) {
        TradeItem item = new TradeItem();
        item.setSkuCode(dto.getSkuCode());
        item.setOriginPrice(dto.getOriginPrice());
        item.setPrice(dto.getPrice());
        item.setDiscountAmount(dto.getDiscountAmount());
        item.setSinglePrice(dto.getSinglePrice());
        item.setQuantity(dto.getQuantity());
        if (item.getPrice() == null) {
            item.setPrice(NumberUtil.div(item.getSinglePrice(), item.getQuantity(), 2));
        }
        return item;
    }

    private void splitOrder(TradeOrderContext ctx, List<TradeItem> itemList) {
        TradeParentOrder parentOrder = ctx.getParentOrder();
        parentOrder.setTotalAmount(BigDecimal.ZERO);
        parentOrder.setPayAmount(BigDecimal.ZERO);
        parentOrder.setDiscountAmount(BigDecimal.ZERO);
        //拆单逻辑
        Map<String, List<TradeItem>> groupmap = itemList.stream().collect(Collectors.groupingBy(TradeItem::getSkuCode));
        List<TradeOrder> tradeOrderList = groupmap.values().stream().map(p ->  {
            TradeOrder tradeOrder = new TradeOrder();
            BigDecimal totalAmount = BigDecimal.ZERO;
            BigDecimal payAmount = BigDecimal.ZERO;
            BigDecimal discountAmount = BigDecimal.ZERO;
            for (TradeItem item : p) {
                totalAmount = NumberUtil.add(totalAmount, NumberUtil.mul(item.getOriginPrice(), item.getQuantity()));
                payAmount = NumberUtil.add(payAmount, item.getSinglePrice());
                discountAmount = NumberUtil.add(discountAmount, item.getDiscountAmount());
            }
            tradeOrder.setTotalAmount(totalAmount);
            tradeOrder.setPayAmount(payAmount);
            tradeOrder.setDiscountAmount(discountAmount);
            tradeOrder.setItemList(p);
            parentOrder.setTotalAmount(NumberUtil.add(parentOrder.getTotalAmount(), totalAmount));
            parentOrder.setPayAmount(NumberUtil.add(parentOrder.getPayAmount(), payAmount));
            parentOrder.setDiscountAmount(NumberUtil.add(parentOrder.getDiscountAmount(), discountAmount));
            return tradeOrder;
        }).toList();
        parentOrder.setOrderList(tradeOrderList);
    }
}
